#include <windows.h>
#include <iostream>

using namespace std;



DWORD WINAPI ThreadProc( LPVOID );
const unsigned int NUM_JOBS = 64;
HANDLE ghDoneEvents[NUM_JOBS];
HANDLE ghStartEvents[NUM_JOBS];

int main( void )
{
	int Threads[NUM_JOBS];;
    HANDLE hThread[NUM_JOBS]; 
    DWORD i, dwEvent, dwWaitResult, dwThreadID; 
	int Capturing(NUM_JOBS);
	LARGE_INTEGER start;
   LARGE_INTEGER end;
   LARGE_INTEGER time;
   LARGE_INTEGER freq;
   double m_time;

	for(int i(0); i<NUM_JOBS; i++){
		Threads[i] = i;
		ghStartEvents[i] = CreateEvent(NULL, TRUE, FALSE, NULL);
		ghDoneEvents[i] = CreateEvent(NULL, TRUE, FALSE, NULL);
	}


    // Create a thread
	for(int i(0); i<NUM_JOBS; i++){

		hThread[i] = CreateThread( 
					 NULL,         // default security attributes
					 0,            // default stack size
					 ThreadProc, 
					 &Threads[i],         // no thread function arguments
					 0,            // default creation flags
					 &dwThreadID); // receive thread identifier
	}

	QueryPerformanceFrequency(&freq);
	while(1){
		//system("cls");

   //get the cpu frequency
   

   //Get starting point
   //Sleep(100);
		QueryPerformanceCounter(&start);

   for(int i(0); i<NUM_JOBS; i++){
	   SetEvent(ghStartEvents[i]);
   }

	WaitForMultipleObjects(NUM_JOBS, ghDoneEvents, TRUE, INFINITE);
	
	for(int i(0); i<NUM_JOBS; i++){
		ResetEvent(ghDoneEvents[i]);

	}


		//system("pause");
   QueryPerformanceCounter(&end);

   time.QuadPart = (double)(end.QuadPart-start.QuadPart) * 1000.0f/freq.QuadPart;
   m_time = time.QuadPart;
   printf("Time: %4.2f\n", m_time);
	}




    // Wait for the thread to signal one of the event objects
	WaitForMultipleObjects(NUM_JOBS, hThread, TRUE, INFINITE);

    // Close event handles
	
   // CloseHandle(ghEvents); 
    system("pause");
    return 0;   
}

DWORD WINAPI ThreadProc( LPVOID lpParam )
{

    // lpParam not used in this example
    //UNREFERENCED_PARAMETER( lpParam);
	int * me = (int*)lpParam;
	int test = *me;
	while(1){
		WaitForSingleObject(ghStartEvents[*me], INFINITE);
		ResetEvent(ghStartEvents[*me]);
		//cout << "THREAD " << *me << endl;
		//printf("Thread: %d\n", *me);
		//printf(".");
		//Sleep(50);
		for(int i(0); i<1000000; i++){
			test = test * 13 + i/2.0f;
			//test = (float)(test%32000)/17.0f;
		}
		printf(" %d ", test);
		//ReleaseMutex(ghMutex[*me]);
		//Sleep(20);
		SetEvent(ghDoneEvents[*me]);
	}
    return 0;
}